#include "ArgParser.h"
#include "Helpers.h"

#include <cstring>

ArgParser::ArgParser(int argc, char *argv[]) : base_path_(argv[0]) {
  for (int i = 1; i < argc; ++i) {
    parseArg(std::string_view(argv[i], strlen(argv[i])));
  }

  constexpr const char *scriptKey = "script";
  auto it = arguments_.find(scriptKey);
  if (it == arguments_.end() || it->second.empty()) {
    fatalError("Missed script arg!");
  }

  script_ = it->second;
  arguments_.erase(it);
}

void ArgParser::parseArg(std::string_view arg) {
  if (arg.substr(0, 2) != "--") {
    fatalError("Missing prefix -- for cmd argument:", arg);
  }

  // shift
  arg = arg.substr(2);

  auto posEq = arg.find('=');

  if (posEq == arg.size() - 1) {
    fatalError("Missing value, but equal ais here for key:", arg);
  }

  std::string argName(arg.substr(0, posEq));
  std::string argValue;

  if (posEq != std::string::npos) {
    argValue = arg.substr(posEq + 1);
  }

  const auto &[it, res] = arguments_.try_emplace(std::move(argName), std::move(argValue));
  if (res == false) {
    fatalError("Argument set twice:", argName);
  }
}

const ArgParser::argContainerT &ArgParser::getArguments() const { return arguments_; }

std::string_view ArgParser::getScript() const { return script_; }

void ArgParser::printArguments() const {
  std::cout << "base_path: " << base_path_ << std::endl;
  std::cout << "script: " << script_ << std::endl;

  for (const auto &[key, val] : arguments_) {
    std::cout << "Argument key: " << key << std::endl;
    std::cout << "Argument val: " << val << std::endl;
  }
}
